import vtkCellArray from "@kitware/vtk.js/Common/Core/CellArray"
import vtkPoints from "@kitware/vtk.js/Common/Core/Points"
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData"
import { BaseLoader } from "./BaseLoader"

export interface GyCell3d {
    // * 所属部件ID
    partId: number
    // * 所属单元ID
    cellId: number
    // * 单元类型
    cellType: string
    // * 顶点数量
    vertexCount: number
    vertexIds: number[]
    // * 顶点坐标
    vertexes: number[]
    // * 每个单元顶点索引
    faces: number[][]
}

// * 类型注解
// eInvalidIndex = -1
// , eElemBL = 1
// , eLinear = 102
// , eLinear2nd = 103
// , eTriangle = 203
// , eQuad = 204
// , eTriangle2nd = 206
// , eQuad2nd = 208
// , ePolygon = 230     //@WYW 2d poly
// , eTet = 304
// , ePyramid = 305
// , ePrism = 306 /*2021.6.27: confirmed as Penta*/
// , eHex = 308
// , eTet2nd = 310
// , ePyramid2nd = 313
// , ePrism2nd = 315 /*2021.6.27: confirmed as Penta2nd*/
// , eHex2nd = 320
// , eBolt_nut = 202
// , eRod = 302
// , ePolyhedron = 340  //@wyw 3d poly
// , eSpring = 402
// , eRbe = 502
// , eRigid = 602
// , eRTri = 2003
// , eTriangleBL = 2003
// , eQuadBL = 2004
// , eTriangleBL2nd = 2006
// , eQuadBL2nd = 2008
// , eTetBL = 3004
// , ePyramidBL = 3005
// , ePrismBL = 3006
// , eHexBL = 3008
// , eTetBL2nd = 3010
// , ePyramidBL2nd = 3013
// , ePrismBL2nd = 3015
// , eHexBL2nd = 3020
// , eVoxel = 3108

export class GyMesh3dLoader extends BaseLoader {
    originData: any
    polyData: any = vtkPolyData.newInstance()
    GyCell3dArr: GyCell3d[] = []
    private pointData: vtkPoints = vtkPoints.newInstance()
    private cellData: vtkCellArray = vtkCellArray.newInstance()

    // * 节点ID
    pointIdsArr = []
    // * 节点坐标
    points = []

    constructor() {
        super()
    }

    createPointData() {
        this.GyCell3dArr.forEach((item: GyCell3d) => {
            this.pointIdsArr.push(...item.vertexIds)
            this.points.push(...item.vertexes)
        })
        this.pointData.setData(this.points, 3)
    }

    createCellData() {
        this.GyCell3dArr.forEach((item: GyCell3d) => {
            item.faces.forEach((face: number[]) => {
                this.cellData.insertNextCell(face)
            })
        })
    }

    parse(data: any) {
        // * 顶点位置偏移 用于计算面的顶点在整体的索引位置
        let offset = 0
        data.forEach((item: any) => {
            const cellId = item[0]
            const partId = item[1]
            const cell3d = {
                partId: partId,
                cellId: cellId,
                cellType: "",
                vertexCount: item[3],
                vertexIds: [],
                vertexes: [],
                faces: [],
            }
            for (let i = 0; i < item[3]; i++) {
                cell3d.vertexIds.push(item[4 + i][0])
                cell3d.vertexes.push(item[4 + i][1])
                cell3d.vertexes.push(item[4 + i][2])
                cell3d.vertexes.push(item[4 + i][3])
            }
            switch (item[2].toString()) {
                /**
                 *  顶点组成的面
                 *  G1 G2 G3
                 *  G1 G2 G4
                 *  G2 G3 G4
                 *  G1 G3 G4
                 */
                case "304":
                    cell3d.cellType = "CTETRA"
                    cell3d.faces.push(
                        [offset + 0, offset + 1, offset + 2],
                        [offset + 0, offset + 1, offset + 3],
                        [offset + 1, offset + 2, offset + 3],
                        [offset + 0, offset + 2, offset + 3]
                    )
                    break
                case "306":
                    cell3d.cellType = "CPENTA"
                    cell3d.faces.push(
                        [offset + 0, offset + 1, offset + 2],
                        [offset + 3, offset + 4, offset + 5],
                        [offset + 0, offset + 1, offset + 4, offset + 3],
                        [offset + 0, offset + 2, offset + 5, offset + 3],
                        [offset + 1, offset + 2, offset + 5, offset + 4]
                    )
                    break
                /**
                 * 顶点组成的面
                 * G1 G2 G3 G4
                 * G1 G4 G8 G5
                 * G1 G2 G6 G5
                 * G5 G6 G7 G8
                 * G3 G2 G6 G7
                 * G3 G4 G8 G7
                 */
                case "308":
                    cell3d.cellType = "CHEXA"
                    cell3d.faces.push(
                        [offset + 0, offset + 1, offset + 2, offset + 3],
                        [offset + 0, offset + 3, offset + 7, offset + 4],
                        [offset + 0, offset + 1, offset + 5, offset + 4],
                        [offset + 4, offset + 5, offset + 6, offset + 7],
                        [offset + 2, offset + 1, offset + 5, offset + 6],
                        [offset + 2, offset + 3, offset + 7, offset + 6]
                    )
                    break
            }
            this.GyCell3dArr.push(cell3d)
            offset += item[3]
        })
        this.createPointData()
        this.createCellData()
        this.originData = data
        this.polyData.setPoints(this.pointData)
        this.polyData.setPolys(this.cellData)
    }
}
